package com.mpgame.core.battle;

import java.util.ArrayList;
import java.util.List;

import com.mpgame.core.model.Monster;
import com.mpgame.core.model.RoundResult;
import com.mpgame.core.utils.MReport;

public class BattleEngine {

    private final Monster m1, m2;
    private int curRound;
    private boolean isBattleEnded;

    private RoundResult roundResult;

    public BattleEngine(Monster m1, Monster m2) {
        this.m1 = m1;
        this.m2 = m2;
        this.m1.setEngineIdx(1);
        this.m2.setEngineIdx(2);
        this.m1.setCurOpponent(m2);
        this.m2.setCurOpponent(m1);
        this.m1.setIdentifier("【怪物m1-黑方】");
        this.m2.setIdentifier("【怪物m2-白方】");
        this.curRound = 1;

        roundResult = new RoundResult();
        roundResult.setCurHealth_mon1(m1.getCurHealth());
        roundResult.setCurHealth_mon2(m2.getCurHealth());
        roundResult.setMaxHealth_mon1(m1.getHealth());
        roundResult.setMaxHealth_mon2(m2.getHealth());
        roundResult.setSkill1pp_mon1(m1.getSkill1().getCurPp());
        roundResult.setSkill1pp_mon2(m2.getSkill1().getCurPp());
        roundResult.setSkill2pp_mon1(m1.getSkill2().getCurPp());
        roundResult.setSkill2pp_mon2(m2.getSkill2().getCurPp());
        roundResult.setSkill3pp_mon1(m1.getSkill3().getCurPp());
        roundResult.setSkill3pp_mon2(m2.getSkill3().getCurPp());
        roundResult.setSkill4pp_mon1(m1.getSkill4().getCurPp());
        roundResult.setSkill4pp_mon2(m2.getSkill4().getCurPp());
        roundResult.setReinforces_mon1(new int[] { 0, 0, 0, 0, 0, 0 });
        roundResult.setReinforces_mon2(new int[] { 0, 0, 0, 0, 0, 0 });
        roundResult.setCur_round_count(1);
    }

    public void doRound(int skill1Index, int skill2Index) {
        m1.setCurSkillByIndex(skill1Index);
        m2.setCurSkillByIndex(skill2Index);

        int m1_cur_hth = m1.getCurHealth();
        int m2_cur_hth = m2.getCurHealth();

        List<Monster> justifiedMonster = justifyOrder(m1, m2);
        Monster mFirst = justifiedMonster.get(0);
        Monster mSecond = justifiedMonster.get(1);

        if (mFirst.getCurSkill() != null && mFirst.getCurSkill().getCurPp() > 0) {
            MReport.Report("【先手】" + mFirst.getIdentifier() + "使用技能 " + mFirst.getCurSkill().getIdentifier() + " ！");
            mFirst.getCurSkill().doRound(mFirst);
        } else {
            MReport.Report("【未出招】" + mFirst.getIdentifier() + "所有技能pp已经耗尽，本回合未能出招！");
        }

        if (mSecond.getCurSkill() != null && mSecond.getCurSkill().getCurPp() > 0) {
            MReport.Report("【后手】" + mSecond.getIdentifier() + "使用技能 " + mSecond.getCurSkill().getIdentifier() + " ！");
            mSecond.getCurSkill().doRound(mSecond);
        } else {
            MReport.Report("【未出招】" + mSecond.getIdentifier() + "所有技能pp已经耗尽，本回合未能出招！");
        }

        mFirst.doStatusRound();
        mSecond.doStatusRound();

        printRoundLog();

        roundResult.setDmg_to_mon1(m1_cur_hth - m1.getCurHealth());
        roundResult.setDmg_to_mon2(m2_cur_hth - m2.getCurHealth());
        roundResult.setCurHealth_mon1(m1.getCurHealth());
        roundResult.setCurHealth_mon2(m2.getCurHealth());
        roundResult.setSkill1pp_mon1(m1.getSkill1().getCurPp());
        roundResult.setSkill1pp_mon2(m2.getSkill1().getCurPp());
        roundResult.setSkill2pp_mon1(m1.getSkill2().getCurPp());
        roundResult.setSkill2pp_mon2(m2.getSkill2().getCurPp());
        roundResult.setSkill3pp_mon1(m1.getSkill3().getCurPp());
        roundResult.setSkill3pp_mon2(m2.getSkill3().getCurPp());
        roundResult.setSkill4pp_mon1(m1.getSkill4().getCurPp());
        roundResult.setSkill4pp_mon2(m2.getSkill4().getCurPp());
        if(mFirst.getCurSkill() != null && mSecond.getCurSkill() != null){
            roundResult.setBattle_log(
                String.format("【%s】先手使用了技能 %s ，【%s】后手使用了技能 %s ！",
                        mFirst.getIdentifier(),
                        mFirst.getCurSkill().getIdentifier(),
                        mSecond.getIdentifier(),
                        mSecond.getCurSkill().getIdentifier()));
        }
        
        roundResult.setReinforces_mon1(m1.getReinforceArray());
        roundResult.setReinforces_mon2(m2.getReinforceArray());
        roundResult.set_mon1_first(mFirst.getEngineIdx() == 1);
        roundResult.setSkillType_mon1(m1.getCurSkill().getSkillType().ordinal());
        roundResult.setSkillType_mon2(m2.getCurSkill().getSkillType().ordinal());
        roundResult.setCur_round_count(curRound);

        System.out.println("roundResult = " + roundResult);

        if (!m1.isAlive() || !m2.isAlive()) {
            isBattleEnded = true;
            if (!m1.isAlive()) {
                roundResult.setWinner_idx(m2.getEngineIdx());
                System.out.println("战斗结束，m2获胜！");
            } else {
                roundResult.setWinner_idx(m1.getEngineIdx());
                System.out.println("战斗结束，m1获胜！");
            }
            return;
        }
        curRound++;
    }

    public RoundResult getRoundResult() {
        return roundResult;
    }

    public boolean getIsBattleEnded() {
        return isBattleEnded;
    }

    /** engineIdx -> Monster */
    public Monster getMonster(int engineIdx) {
        return m1.getEngineIdx() == engineIdx ? m1 : m2;
    }

    public void printRoundLog() {
        System.out.println("===第 " + curRound + " 回合战报===");
        System.out.println("m1血量=" + m1.getCurHealth() + "技能pp:" + m1.getSkill1().getCurPp() + "|"
                + m1.getSkill2().getCurPp() + "|" + m1.getSkill3().getCurPp() + "|" + m1.getSkill4().getCurPp() + "|");
        System.out.println("m2血量=" + m2.getCurHealth() + "技能pp:" + m2.getSkill1().getCurPp() + "|"
                + m2.getSkill2().getCurPp() + "|" + m2.getSkill3().getCurPp() + "|" + m2.getSkill4().getCurPp() + "|");
    }

    private List<Monster> justifyOrder(Monster m1, Monster m2) {
        List<Monster> res = new ArrayList<>();

        // 看是否有pp或是否为null
        if (m1.getCurSkill() != null && m2.getCurSkill() == null) {
            res.add(m1);
            res.add(m2);
            return res;
        } else if (m1.getCurSkill() == null && m2.getCurSkill() != null) {
            res.add(m2);
            res.add(m1);
            return res;
        } else if (m1.getCurSkill() == null && m2.getCurSkill() == null) {
            if (Math.random() > 0.5) {
                res.add(m1);
                res.add(m2);
            } else {
                res.add(m2);
                res.add(m1);
            }
            return res;
        }
        // 看先制等级
        if (m1.getCurSkill().getPriority() > m2.getCurSkill().getPriority()) {
            res.add(m1);
            res.add(m2);
            return res;
        } else if (m1.getCurSkill().getPriority() < m2.getCurSkill().getPriority()) {
            res.add(m2);
            res.add(m1);
            return res;
        }
        // 看精灵当前速度
        if (m1.getCurSpeed() > m2.getCurSpeed()) {
            res.add(m1);
            res.add(m2);
        } else if (m1.getCurSpeed() < m2.getCurSpeed()) {
            res.add(m2);
            res.add(m1);
        } else {
            if (Math.random() > 0.5) {
                res.add(m1);
                res.add(m2);
            } else {
                res.add(m2);
                res.add(m1);
            }
        }
        return res;
    }
}
